﻿<%@ Page Title="VisualCron - web client" Language="C#" MasterPageFile="~/Site.master"
    AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" %>

<%@ Import Namespace="App_Code.Common" %>
<%@ Import Namespace="App_Code.Helpers" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:ScriptManager runat="server" />
    <script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.signalR.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.longtouch.js" type="text/javascript"></script>
    <script src="signalr/hubs" type="text/javascript"></script>
    <script src="JS/ArrayHelper.js" type="text/javascript"></script>
    <script src="JS/VisualCronData.js" type="text/javascript"></script>
    <script src="JS/JobsObject.js" type="text/javascript"></script>
    <script src="JS/Connections.js" type="text/javascript"></script>
    <script src="JS/LoadManager.js" type="text/javascript"></script>
    <script type="text/javascript">

        // password reenter dialog methods

        LoginButton_OnClientClicked = function(sender, eventArgs) {
            var username = $find('<%= UsernameText.ClientID %>').get_value();
            var password = $find('<%= PasswordText.ClientID %>').get_value();

            visualCron.connect(window._currentVCConnection.ConnectionId, username, password);

            HideEnterPasswordWindow();
            ConnectButton_SetEnabled(false);
        }

        CancelLoginButton_OnClientClicked = function(sender, eventArgs) {
            HideEnterPasswordWindow();
            ConnectButton_SetEnabled(true);
        }

        ShowEnterPasswordWindow = function(isError, vcConnection) {
            var wnd = $find('<%= EnterPasswordWindow.ClientID %>');

            window._currentVCConnection = vcConnection;

            if (isError) 
            {
                wnd.set_title("Authentication error");
            }
            else 
            {
                wnd.set_title("Server authentication");
            }

            $find('<%= UsernameText.ClientID %>').set_value(vcConnection.Username);
            $find('<%= PasswordText.ClientID %>').set_value(vcConnection.Password);

            wnd.show();
        }

        HideEnterPasswordWindow = function() {
            var wnd = $find('<%= EnterPasswordWindow.ClientID %>');
            wnd.close();
        }

        //context menu methods

        // shows task context menu for selected row
        TaskGrid_RowContextMenu = function (sender, eventArgs) {
                var menu = $find("<%=TasksContextMenu.ClientID %>");
                var evt = eventArgs.get_domEvent();

                var index = eventArgs.get_itemIndexHierarchical();
                document.getElementById("<%= tasksGridClickedGridId.ClientID %>").value = sender.ClientID;
                document.getElementById("<%= tasksGridClickedRowIndex.ClientID %>").value = index;

                sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);

                menu.show(evt);

                evt.cancelBubble = true;
                evt.returnValue = false;

                if (evt.stopPropagation) {
                    evt.stopPropagation();
                    evt.preventDefault();
                }
            }

        // shows job context menu for selected row
            JobsGrid_RowContextMenu = function (sender, eventArgs) {
                var menu = $find("<%=JobsContextMenu.ClientID %>");
                var evt = eventArgs.get_domEvent();

                var index = eventArgs.get_itemIndexHierarchical();
                document.getElementById("<%= radGridClickedGridId.ClientID %>").value = sender.ClientID;
                document.getElementById("<%= radGridClickedRowIndex.ClientID %>").value = index;

                sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);

                menu.show(evt);

                evt.cancelBubble = true;
                evt.returnValue = false;

                if (evt.stopPropagation) {
                    evt.stopPropagation();
                    evt.preventDefault();
                }
            }

            JobsContextMenu_OnClicked = function (sender, args) {
                var itemValue = args.get_item().get_value();
                var clickedElement = args.get_targetElement();
                var index = document.getElementById("<%= radGridClickedRowIndex.ClientID %>").value;

                var jobsGrid = $find(document.getElementById("<%= radGridClickedGridId.ClientID %>").value);
                var dataItem = jobsGrid.get_masterTableView().get_dataItems()[index];

                var serverId = window.visualCronData.getServerByJobGrid(jobsGrid.ClientID);

                switch(itemValue) {
                    case "Activate":
                        window.visualCron.activateJob(serverId, dataItem.getDataKeyValue("Id"));
                        break;
                    case "Deactivate":
                        window.visualCron.deactivateJob(serverId, dataItem.getDataKeyValue("Id"));
                        break;
                    case "Run":
                        window.visualCron.runJob(serverId, dataItem.getDataKeyValue("Id"), '');
                        break;
                    case "Stop":
                        window.visualCron.stopJob(serverId, dataItem.getDataKeyValue("Id"));
                        break;
                }
            }

            TasksContextMenu_OnClicked = function (sender, args) {
                var itemValue = args.get_item().get_value();
                var clickedElement = args.get_targetElement();
                var index = document.getElementById("<%= tasksGridClickedRowIndex.ClientID %>").value;

                var tasksGrid = $find(document.getElementById("<%= tasksGridClickedGridId.ClientID %>").value);
                var dataItem = tasksGrid.get_masterTableView().get_dataItems()[index];

                var jobAndServer = window.visualCronData.getServerAndJobByGrid(tasksGrid.ClientID);

                if (jobAndServer) {
                    switch(itemValue) {
                        case "Activate":
                            window.visualCron.activateTask(jobAndServer.serverId, jobAndServer.jobId, dataItem.getDataKeyValue("TaskId"));
                            break;
                        case "Deactivate":
                            window.visualCron.deactivateTask(jobAndServer.serverId, jobAndServer.jobId, dataItem.getDataKeyValue("TaskId"));
                            break;
                        case "Run":
                            window.visualCron.runTask(jobAndServer.serverId, jobAndServer.jobId, dataItem.getDataKeyValue("TaskId"));
                            break;
                        case "Stop":
                            window.visualCron.stopTask(jobAndServer.serverId, jobAndServer.jobId, dataItem.getDataKeyValue("TaskId"));
                            break;
                        case "RunJob":
                            window.visualCron.runJob(jobAndServer.serverId, jobAndServer.jobId, dataItem.getDataKeyValue("TaskId"));
                    }
                }
            }

            OnLongTouch = function (event) {

                var sender = event.vc_sender;

                while (!sender.control) {
                    sender = sender.offsetParent;
                }

                var ctrl = sender.control;
                while (ctrl.get_parent && ctrl.get_parent()) {
                    ctrl = ctrl.get_parent();
                    if (ctrl instanceof Telerik.Web.UI.RadGrid) {
                        //blinks if shown without delay - not really sure why
                        $(ctrl).delay(50).queue(function (next) { ctrl._contextmenu(event.vc_context); next(); });
                        return;
                    }
                }
            }

        //eof context menu methods
        

        function debbugwrite(text) {
            //$('#debugout').html($('#debugout').html() + " "+text);
        }


        JobsGrid_OnDataBinding= function(sender, args) {
        }

        ServerGrid_HierarchyExpanding = function(sender, args) {
            updateJobs(sender, args);
        }

        JobGrid_HierarchyExpanding = function(sender, args) {
             updateTasks(sender, args);
        }

        
        // adds item to Connection list or Server filter list comboboxes
        ComboboxAddItem = function(combo, collectionItem, useServerId, lastSelected) {
                    var item = new Telerik.Web.UI.RadComboBoxItem(); 
                    item.set_text(collectionItem.Host); 
                    if (useServerId){
                        if (collectionItem.UserServerId) {
                            item.set_value(collectionItem.UserServerId);
                        }
                        else {
                            item.set_value('none');
                        }
                    }
                    else {
                        item.set_value(collectionItem.ConnectionId);
                    }
                    if (collectionItem.Connected) {
                        item.set_imageUrl("images/ServerConnected.png");
                        item.get_attributes().setAttribute("Connected", "True");
                    }
                    else {
                        item.set_imageUrl("images/ServerDisconnected.png");
                        item.get_attributes().setAttribute("Connected", "False");
                    }

                    combo.get_items().add(item);            

                    if (lastSelected) {
                        item.select();
                    }

        }

        ConnnectionsListUpdate = function(listConnections) {
            window.visualCronConnections.set_connections(listConnections);

            if(listConnections){
                var combo = $find("<%= ConnectionsList.ClientID %>"); 
                var lastSelected = combo.get_selectedIndex();
                combo.clearItems();
                for (var i = 0; i < listConnections.length; i++){
                    ComboboxAddItem(combo, listConnections[i], false, (i==lastSelected));
                }
                ConnnectionsList_OnClientItemsRequested(combo, null);
            }

            if(listConnections) {
                var toolBar = $find("<%= FilterToolBar.ClientID %>");
                var toolbarbutton = toolBar.findItemByValue("ServerFilterContainer");
                var filter = toolbarbutton.findControl("ServerFilter");

                var lastSelectedFilter = filter.get_selectedIndex();
            
                filter.clearItems();

                var item = new Telerik.Web.UI.RadComboBoxItem(); 
                item.set_text("All servers"); 
                item.set_value("all_servers");
                filter.get_items().add(item);

                for (var i = 0; i < listConnections.length; i++){
                    ComboboxAddItem(filter, listConnections[i], true, (i+1==lastSelectedFilter));
                }

                ConnnectionsList_OnClientItemsRequested(filter, null);
            }
        }

        ConnnectionsList_SetSelected = function(serverId) {
            var combo = $find("<%= ConnectionsList.ClientID %>"); 
            var items = combo.get_items();

            var connection = window.visualCronConnections.getConnectionByUserServerId(serverId);
            if (!connection){
                return;
            }

            for (var i=0; i < items.get_count(); i++) {
                var item = items.getItem(i);
                if (item.get_value() == connection.ConnectionId) {
                    item.select();
                    return;
                }
            }
        }

        ConnnectionsList_OnClientSelectedIndexChanged = function(sender, eventArgs) {
            var item = eventArgs.get_item();
            
            var btn = $find('<%= btnConnect.ClientID %>'); 
            var primaryIconElement = btn.get_primaryIconElement();
            var imagePath = '';

            if (item.get_attributes().getAttribute("Connected") == "True" )
            {
               btn.set_text("Disconnect");
               imagePath = "url('images/ServerDisconnected.png')";
            }
            else {
               btn.set_text("Connect");
               imagePath = "url('images/ServerConnected.png')";
            }
            //this will let image not to change back on hover
            btn._iconData.primaryIconUrl = imagePath;

            $telerik.$(primaryIconElement).css("background-image", imagePath);
        }

        FilterButton_OnClientClicked = function(sender, eventArgs){
            var jobFilter = $('.jobFilter').val('');
            var taskFilter = $('.taskFilter').val('');
            var toolBar = $find("<%= FilterToolBar.ClientID %>");
            var toolbarbutton = toolBar.findItemByValue("ServerFilterContainer");
            var serverFilter = toolbarbutton.findControl("ServerFilter");

            if (serverFilter.get_items().get_count() > 0){
                serverFilter.get_items().getItem(0).select();
            }

            window.visualCronData.filterJobs(jobFilter.val());
            window.visualCronData.filterTasks(taskFilter.val());
        }

        ServerFilter_OnClientSelectedIndexChanged = function(sender, eventArgs) {
            var item = eventArgs.get_item();
            window.visualCronData.filterServers(item.get_value());
        }

        //hack to show icon inside of combobox input
        showImageOnSelectedItemChanging = function(sender, eventArgs) {
            var input = sender.get_inputDomElement();
            
            if (eventArgs.get_item().get_imageUrl()) {
                input.style.background = "url(" + eventArgs.get_item().get_imageUrl() + ") no-repeat";
            }
        }
 
        // sets selected item in combobox
        ConnnectionsList_OnClientItemsRequested = function(combo, eventarqs)
           {
            combo.trackChanges();

            var item = combo.get_selectedItem();

            if (combo.get_items().get_count() > 0){
                if (item) {
                    item.select();
                }
                else{ 
                combo.get_items().getItem(0).select();
                }
                combo.updateClientState();
                combo.commitChanges();
            }
        }

        Connect_OnClientClicked = function(sender, args){
            var combo = $find("<%= ConnectionsList.ClientID %>"); 
            var item = combo.get_selectedItem();

            ConnectButton_SetEnabled(false);

            if (item.get_attributes().getAttribute("Connected") == "True" ){
               visualCron.disconnect(item.get_value())
                   .done(function(result) { if (!result) {ConnectButton_SetEnabled(true); } })
                   .fail(function() { ConnectButton_SetEnabled(true); });
            }
            else {
                var connection = window.visualCronConnections.getConnectionById(item.get_value());

                if (connection.Username == '') {
                    // in case connection password is empty and this is not a local connection
                    // we ask user to supplay another credentials
                    ShowEnterPasswordWindow(false, connection);
                }
                else {
                    visualCron.connect(connection.ConnectionId, '', '');
                }
            }

        }

        ConnectButton_SetEnabled = function(enabled) {
            var btn = $find("<%=  btnConnect.ClientID %>");
            btn.set_enabled(enabled);
        }

        ManageConnections_OnClientClicked = function(){
            var oWnd = $find("<%=ConnectionsWindow.ClientID%>");
            oWnd.show();
        }

        TasksGrid_ApplyTasks = function(serverId, jobId, taskGridControlId, tasksControlId){

                var tasks = $.parseJSON($('#'+tasksControlId).val());
               
                window.visualCronData.addTasks(serverId, jobId, tasks, taskGridControlId, true);

                bindLongTouch();

        }

        JobsGrid_ApplyJobs = function(serverId, jobGridControlId, jobDataControlId) {
                var jobs = $.parseJSON($('#'+jobDataControlId).val());

                window.visualCronData.addJobs(serverId, jobs, jobGridControlId);

                bindLongTouch();
        }

        // happens when server tree node gets data from server on first expand
        ServerTree_OnClientNodePopulated = function(sender, args) {
            window.loadManager.OnNodePopulated(args.get_node());
        }

        ServerTree_OnClientNodePopulating = function(sender, args) {
            window.loadManager.AddNodeExpanding(args.get_node());
        }

        ServerTree_OnClientNodeClicked = function(sender, args) {
            //console.log('ServerTree_OnClientNodeClicked ');

            //this code assumes that only root level nodes have values and that these values contain ServerId

            var node = args.get_node();
            if (!node.get_value()) {
                node = node.get_parent();
            }

            if (!node.get_value()) {
                return;
            }
            
            ConnnectionsList_SetSelected(node.get_value());
        }

        // binds longtouch event habdlers to grid rows - used for mobile devices
        function bindLongTouch() {
            var items = $('.rgRow td:not(.rgExpandCol),.rgAltRow td:not(.rgExpandCol)');
                
            items.bind('longtouch', OnLongTouch);
        }

        // prevents session from being dropped
        function KeepAlive() {
            window.visualCron.keepAlive();
            setTimeout(function () { KeepAlive(); }, <%= HttpContext.Current.Session.Timeout * 30000 %>); // TimeoutInMinutes * 60 * 1000 (milliseconds) / 2 
        }

        $(function () {
            window.loadManager = new VisualCron.LoadManager();

            var visualCron = $.connection.visualCron;

            var visualCronData = new VisualCron.VisualCronData();

            window.visualCronData = visualCronData;

            visualCronData.set_serverTreeClientID('<%= ServerTree.ClientID %>');

            visualCronData.set_serversList(<%= ServerList %>);

            window.visualCronConnections = new VisualCron.Connections();

            //ConnnectionsListUpdate();

            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_endRequest(function () { window.loadManager.OnAsyncRequestFinished(); });   

            bindLongTouch();


            jobGridAddRecord = function(serverId, job) {
            }

            $.connection.hub.start(function () {
                visualCron.start($('#<%=hdnSessionId.ClientID %>').val());


                window.visualCron = visualCron;
                KeepAlive();
            });


            visualCron.serverConnected = function (diff) {
                visualCronData.addServer(diff);

                ConnectButton_SetEnabled(true);

            }

            visualCron.serverDisconnected = function (serverId) {
                visualCronData.removeServer(serverId);

                ConnectButton_SetEnabled(true);
            }

            visualCron.connectionError = function(connectionId, isLoginError, message) {
                if (isLoginError) {
                    var connection = window.visualCronConnections.getConnectionById(connectionId);

                    if (connection) {
                        ShowEnterPasswordWindow(true, connection);
                        return;
                    }
                }

                ConnectButton_SetEnabled(true);
                window.alert(message);
            }

            visualCron.jobsUpdated = function (serverId, jobs) {
                //console.log('jobs updated: ' + serverId + ' list: ' + jobs);
            }

            visualCron.jobAdded = function(serverId, job) {
                visualCronData.addSingleJob(serverId, job);
            }

            visualCron.jobRemoved = function(serverId, job) {
                visualCronData.removeJob(serverId, job);
            }

            visualCron.jobUpdated = function(serverId, job) {
                visualCronData.updateJob(serverId, job);
            }
            
            visualCron.taskAdded = function(serverId, jobId, task) {
                visualCronData.addSingleTask(serverId, jobId, task);
            }

            visualCron.taskRemoved = function(serverId, jobId, task) {
                visualCronData.removeTask(serverId, jobId, task);
            }

            visualCron.taskUpdated = function(serverId, jobId, task) {
                visualCronData.updateTask(serverId, jobId, task);
            }

            visualCron.connectionStateChanged = function(listConnections) {
                ConnnectionsListUpdate(listConnections);
            }

           
            updateJobs = function(sender, args) {
                var serverID = args.getDataKeyValue("ServerId");
                var nestedViewItem = args.get_nestedViewItem();

                var ctrl = $telerik.findControl(nestedViewItem, "JobGrid");

                
                visualCronData.addJobs(serverID, null, ctrl.ClientID);

                visualCron.getJobs(serverID).done(function(jobs) {

                    visualCronData.addJobs(serverID, jobs, null);

                });
            }

            updateTasks = function(sender, args) {
                var jobId = args.getDataKeyValue("Id");
                var nestedViewItem = args.get_nestedViewItem();

                var tasksGrid = $telerik.findControl(nestedViewItem, "TaskGrid");

                if (!tasksGrid){
                    
                    var btn = $get("btnUpdate", nestedViewItem);

                    var serverId = visualCronData.getServerByJobGrid(sender.ClientID);

                    window.loadManager.AddTaskGridToCall(serverId, jobId, btn);
                }
            }

            $('.jobFilter').keyup(function() {
                var filter = $('.jobFilter');

                var toolBar = $find("<%= FilterToolBar.ClientID %>");
                var toolbarbutton = toolBar.findItemByValue("FilterContainer");
                var combo = toolbarbutton.findControl("FilterCombo");

                var selectedFilter = combo.get_selectedItem();

                if (filter.val() == '' || filter.val().length > 1) {

                    switch(selectedFilter.get_value()){
                        case "JobName":
                            window.visualCronData.filterJobs(filter.val());
                            return;
                    }
                }
            });

            // prevents cursor to be shown in comboboxes
            $(".rcbInput").focus(function(event) {
                event.preventDefault();
                this.blur();
            });    

        });

        JobGrid_OnCommand = function(sender, args) {
            switch (args.get_commandName()){
                case "Sort": 
                     var expressions = sender.get_masterTableView().get_sortExpressions();

                     var fieldName = "";
                     var sortOrder = "";
                     if (expressions._array.length > 0) {
                        var expression = expressions._array[0];
                        fieldName = expression.get_fieldName();
                        sortOrder = expression.get_sortOrder();
                     }

                     window.visualCronData.sortJobs(sender.ClientID, fieldName, sortOrder);
                     args.set_cancel(true);
                     break;
            }
        }



    </script>
    <div id="header">
        <div class="panelConnect">
            <asp:UpdatePanel runat="server" ID="stubUp" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Button runat="server" ID="stubUpdate" ClientIDMode="Static" Style="display: none;" />
                </ContentTemplate>
            </asp:UpdatePanel>
            <telerik:RadComboBox ID="ConnectionsList" runat="server" CssClass="ImageCombobox"
                OnClientSelectedIndexChanged="ConnnectionsList_OnClientSelectedIndexChanged" AllowCustomText="false" EnableLoadOnDemand="false" MarkFirstMatch="false"
                OnClientSelectedIndexChanging="showImageOnSelectedItemChanging" OnClientItemsRequested="ConnnectionsList_OnClientItemsRequested" EnableViewState="false">
            </telerik:RadComboBox>
            <telerik:RadButton ID="ManageConnections" runat="server" OnClientClicked="ManageConnections_OnClientClicked"
                AutoPostBack="false" Width="22px" EnableViewState="false">
                <Icon PrimaryIconUrl="~/images/manageservers16.gif"/>
            </telerik:RadButton>
            <telerik:RadButton ID="btnConnect" runat="server" Text="Connect" OnClientClicked="Connect_OnClientClicked"
                AutoPostBack="false" EnableViewState="false">
                <Icon PrimaryIconUrl="~/images/ServerConnected.png" />
            </telerik:RadButton>
        </div>
        <div class="loginPanel">
            <asp:Panel runat="server" ID="panelUserInfo" Visible="false" EnableViewState="false">
                <asp:Label ID="LoggenInLabel" runat="server" Text="Logged in as: " CssClass="inlineblock"  EnableViewState="false"/>
                <asp:Label ID="labelUsername" runat="server" Width="200px" CssClass="ellipsis"  EnableViewState="false"/>
                <asp:LinkButton ID="LogoutButton" runat="server" OnClick="LogoutButton_OnClick" Text="Log out" CssClass="inlineblock"  EnableViewState="false"/>
            </asp:Panel>
            <asp:Panel runat="server" ID="panelLogin" Visible="false" EnableViewState="false">
                <asp:Label ID="LoginLabel" runat="server" Text="You can: "  EnableViewState="false"/>
                <asp:HyperLink ID="LoginLink" runat="server" NavigateUrl="~/Login.aspx" Text="Log in"  EnableViewState="false"/>
            </asp:Panel>
        </div>
    </div>
    <div class="panelFilter">
        <telerik:RadToolBar runat="server" ID="FilterToolBar" OnClientButtonClicked="FilterButton_OnClientClicked" EnableViewState="false">
            <Items>
                <telerik:RadToolBarButton Value="ServerFilterContainer">
                    <ItemTemplate>
                        <telerik:RadComboBox EnableViewState="false" ID="ServerFilter" runat="server" OnClientSelectedIndexChanged="ServerFilter_OnClientSelectedIndexChanged" CssClass="ImageCombobox"
                            OnClientSelectedIndexChanging="showImageOnSelectedItemChanging" OnClientItemsRequested="ConnnectionsList_OnClientItemsRequested" EnableTextSelection="false"/>
                    </ItemTemplate>
                </telerik:RadToolBarButton>
                <telerik:RadToolBarButton IsSeparator="true" Style="margin: 0 5px 0 5px" />
                <telerik:RadToolBarButton Value="FilterContainer">
                    <ItemTemplate>
                        <telerik:RadComboBox ID="FilterCombo" runat="server" Width="90px">
                            <Items>
                                <telerik:RadComboBoxItem Text="Job name" Value="JobName" Selected="true" />
                            </Items>
                        </telerik:RadComboBox>
                        <telerik:RadTextBox ID="JobFilter" runat="server" CssClass="jobFilter" />
                    </ItemTemplate>
                </telerik:RadToolBarButton>
                <telerik:RadToolBarButton ID="ClearFilter" runat="server" Text="Clear filter" AutoPostBack="False"
                    Value="Add" />
            </Items>
        </telerik:RadToolBar>
    </div>
    <asp:HiddenField runat="server" ID="hdnSessionId" />
    <asp:HiddenField runat="server" ID="radGridClickedRowIndex" />
    <asp:HiddenField runat="server" ID="radGridClickedGridId" />
    <asp:HiddenField runat="server" ID="tasksGridClickedRowIndex" />
    <asp:HiddenField runat="server" ID="tasksGridClickedGridId" />
    <asp:HiddenField runat="server" ID="hdnUserServerId" ClientIDMode="Static" />
    <asp:HiddenField runat="server" ID="hdnJobId" ClientIDMode="Static" />
    <asp:HiddenField runat="server" ID="gridToShow" />
    <div>
        <telerik:RadTreeView ID="ServerTree" runat="server" OnNodeExpand="ServerTree_OnNodeExpand"
            OnClientNodePopulated="ServerTree_OnClientNodePopulated" OnClientNodePopulating="ServerTree_OnClientNodePopulating" OnClientNodeClicked="ServerTree_OnClientNodeClicked">
            <NodeTemplate>
                <asp:UpdatePanel runat="server" ID="upJobGrid" UpdateMode="Conditional">
                    <ContentTemplate>
                        <asp:Button runat="server" ID="btnJobGridSetVisible" OnClick="JobGridSetVisible_OnClick"
                            Style="display: none;" ClientIDMode="Static" />
                        <telerik:RadGrid runat="server" ID="JobGrid" AllowPaging="True" AllowSorting="True" 
                            GridLines="None" Width="100%" PageSize="<%# Constants.JOB_GRID_PAGE_SIZE %>"
                            Visible="false" >
                            <ClientSettings AllowRowHide="True" AllowColumnsReorder="False" EnableRowHoverStyle="true">
                                <ClientEvents OnRowContextMenu="JobsGrid_RowContextMenu" OnHierarchyExpanded="JobGrid_HierarchyExpanding" OnCommand="JobGrid_OnCommand"/>
                                <Resizing AllowColumnResize="True" />
                            </ClientSettings>
                            <MasterTableView AutoGenerateColumns="false" DataKeyNames="Id,JobName,TaskCount"
                                ClientDataKeyNames="Id,JobName,TaskCount" HierarchyLoadMode="Client">
                                <Columns>
                                    <telerik:GridImageColumn DataType="System.String" HeaderText="St" 
                                        ImageWidth="16px" ImageHeight="16px" HeaderStyle-Width="26px" UniqueName="Active"
                                        DataImageUrlFields="Active" DataImageUrlFormatString="Images\Activity{0}.gif" DataAlternateTextFormatString="{0}" />
                                    <telerik:GridBoundColumn DataType="System.String" DataField="JobName" UniqueName="JobName"
                                        HeaderText="Job Name" HeaderStyle-Width="145px" SortExpression="JobName"/>
                                    <telerik:GridBoundColumn DataType="System.String" DataField="Description" UniqueName="Description"
                                        HeaderText="Description" HeaderStyle-Width="230px" />
                                    <telerik:GridBoundColumn DataType="System.String" DataField="Result" UniqueName="Result"
                                        HeaderText="Result" HeaderStyle-Width="55px" />
                                    <telerik:GridImageColumn DataType="System.String" ImageWidth="16px" ImageHeight="16px"
                                        HeaderStyle-Width="26px" UniqueName="ResultImage" DataImageUrlFields="Result"
                                        DataImageUrlFormatString="Images\Result\res_{0}.png" DataAlternateTextFormatString="{0}" />
                                    <telerik:GridBoundColumn DataType="System.String" DataField="NextRunStr" UniqueName="NextRunStr"
                                        HeaderText="Next run" HeaderStyle-Width="180px" />
                                    <telerik:GridBoundColumn DataType="System.String" DataField="LastRunStr" UniqueName="LastRunStr"
                                        HeaderText="Last run" HeaderStyle-Width="180px" />
                                    <telerik:GridBoundColumn DataType="System.String" DataField="Status" UniqueName="Status"
                                        HeaderText="Status" HeaderStyle-Width="55px" />
                                    <telerik:GridBoundColumn DataType="System.String" DataField="Id" UniqueName="ID"
                                        Visible="false" />
                                    <telerik:GridBoundColumn DataType="System.Int32" DataField="TaskCount" UniqueName="TaskCount"
                                        Visible="false" />
                                </Columns>
                                <NestedViewTemplate>
                                    <asp:UpdatePanel ID="upTasks" runat="server" UpdateMode="Conditional">
                                        <ContentTemplate>
                                            <asp:Button ID="btnUpdate" OnClick="LoadTasks" runat="server" ClientIDMode="Static"
                                                Style="display: none;" />
                                            <telerik:RadGrid EnableViewState="false" runat="server" ID="TaskGrid" AllowPaging="False"
                                                AllowSorting="False" GridLines="None" Width="97%" PageSize="100" Visible="false">
                                                <ClientSettings AllowColumnHide="True" AllowRowHide="True" AllowColumnsReorder="True"
                                                    ReorderColumnsOnClient="True" EnableRowHoverStyle="true">
                                                    <Resizing EnableRealTimeResize="False" ResizeGridOnColumnResize="False" AllowColumnResize="True"
                                                        ClipCellContentOnResize="False"></Resizing>
                                                    <ClientEvents OnRowContextMenu="TaskGrid_RowContextMenu" />
                                                </ClientSettings>
                                                <MasterTableView TableLayout="Fixed" AutoGenerateColumns="false" DataKeyNames="TaskId"
                                                    ClientDataKeyNames="TaskId">
                                                    <Columns>
                                                        <telerik:GridImageColumn DataType="System.String" HeaderText="" DataImageUrlFormatString="Images\Activity{0}.gif"
                                                            DataImageUrlFields="Active" ImageWidth="16px" ImageHeight="16px" HeaderStyle-Width="26px" />
                                                        <telerik:GridImageColumn DataType="System.String" HeaderText="" DataImageUrlFormatString="TaskImage.aspx?TaskName={0}"
                                                            DataImageUrlFields="TaskType" ImageWidth="16px" ImageHeight="16px" HeaderStyle-Width="26px" />
                                                        <telerik:GridBoundColumn DataType="System.String" DataField="TaskName" UniqueName="TaskName"
                                                            HeaderText="Task Name" HeaderStyle-Width="170px" />
                                                        <telerik:GridBoundColumn DataType="System.String" DataField="Result" UniqueName="Result"
                                                            HeaderText="Result" HeaderStyle-Width="55px" />
                                                        <telerik:GridImageColumn DataType="System.String" ImageWidth="16px" ImageHeight="16px"
                                                            HeaderStyle-Width="26px" UniqueName="ResultImage" DataImageUrlFields="Result"
                                                            DataImageUrlFormatString="Images\Result\res_{0}.png" DataAlternateTextFormatString="{0}" />
                                                        <telerik:GridBoundColumn DataType="System.String" DataField="LastRunStr" UniqueName="LastRunStr"
                                                            HeaderText="Last run" HeaderStyle-Width="175px" />
                                                        <telerik:GridBoundColumn DataType="System.String" DataField="TaskId" UniqueName="TaskId"
                                                            HeaderStyle-Width="170px" Visible="False" />
                                                    </Columns>
                                                </MasterTableView>
                                            </telerik:RadGrid>
                                        </ContentTemplate>
                                    </asp:UpdatePanel>
                                </NestedViewTemplate>
                            </MasterTableView>
                        </telerik:RadGrid>
                    </ContentTemplate>
                </asp:UpdatePanel>
            </NodeTemplate>
        </telerik:RadTreeView>
        <span class="versionInfo"><%= GeneralHelper.GetVisualCronVersionInfo() %></span>
        <telerik:RadContextMenu ID="JobsContextMenu" runat="server" OnClientItemClicked="JobsContextMenu_OnClicked" EnableViewState="false">
            <Items>
                <telerik:RadMenuItem Text="Run Job" Value="Run" ImageUrl="~/images/runjob.gif"/>
                <telerik:RadMenuItem Text="Stop Job" Value="Stop" ImageUrl="~/images/stopjob.gif"/>
                <telerik:RadMenuItem IsSeparator="true" />
                <telerik:RadMenuItem Text="Activate Job" Value="Activate" ImageUrl="~/images/active.gif"/>
                <telerik:RadMenuItem Text="Deactivate Job" Value="Deactivate" ImageUrl="~/images/inactive.gif"/>
            </Items>
        </telerik:RadContextMenu>
        <telerik:RadContextMenu ID="TasksContextMenu" runat="server" OnClientItemClicked="TasksContextMenu_OnClicked" EnableViewState="false">
            <Items>
                <telerik:RadMenuItem Text="Run Task" Value="Run" ImageUrl="~/images/runjob.gif"/>
                <telerik:RadMenuItem Text="Run Job from Task" Value="RunJob" />
                <telerik:RadMenuItem Text="Stop Task" Value="Stop" ImageUrl="~/images/stopjob.gif"/>
                <telerik:RadMenuItem IsSeparator="true" />
                <telerik:RadMenuItem Text="Activate Task" Value="Activate" ImageUrl="~/images/active.gif"/>
                <telerik:RadMenuItem Text="Deactivate Task" Value="Deactivate" ImageUrl="~/images/inactive.gif"/>
            </Items>
        </telerik:RadContextMenu>
        <telerik:RadWindowManager ID="RadWindowManager1" runat="server" EnableViewState="false">
            <Windows>
                <telerik:RadWindow ID="ConnectionsWindow" runat="server" NavigateUrl="~/Connections.aspx"
                    Title="Manage servers" IconUrl="~/images/visualcron.png" Width="635px" Height="400px" EnableViewState="false">
                </telerik:RadWindow>
                <telerik:RadWindow ID="EnterPasswordWindow" runat="server" Title="Server authentication"
                    IconUrl="~/images/visualcron.png" Width="200px" Height="150px" Behaviors="None"
                    Modal="true" EnableViewState="false">
                    <ContentTemplate>
                        <table>
                            <tr>
                                <td colspan="2">
                                    <telerik:RadTextBox runat="server" ID="UsernameText" Label="Username:" />
                                </td>
                            </tr>
                            <tr>
                                <td colspan="2">
                                    <telerik:RadTextBox runat="server" ID="PasswordText" Label="Password:" TextMode="Password" />
                                </td>
                            </tr>
                            <tr>
                                <td colspan="2">
                                    <telerik:RadButton runat="server" ID="LoginButton" Text="Login" OnClientClicked="LoginButton_OnClientClicked"
                                        AutoPostBack="false" />
                                    <telerik:RadButton runat="server" ID="CancelLoginButton" Text="Cancel" OnClientClicked="CancelLoginButton_OnClientClicked"
                                        AutoPostBack="false" />
                                </td>
                            </tr>
                        </table>
                    </ContentTemplate>
                </telerik:RadWindow>
            </Windows>
        </telerik:RadWindowManager>
    </div>
</asp:Content>
